home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / apps / math / ols.zoo / ols.c < prev    next >
C/C++ Source or Header  |  1993-04-16  |  7KB  |  257 lines

  1. /* This file contains the main program, and the code which parses
  2.  * the commandline.
  3.  */
  4.  
  5. #include <math.h>
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include <stdlib.h>
  9.  
  10. #include "utils.h"
  11. #include "patchlevel.h"
  12.  
  13. /* Local prototypes. */
  14. int ols (char **labels, float **data, int K, int ObsNum,
  15.      int purebeta, int pscript, int epp,
  16.      int *maptable, int labelcount);
  17. int CommandLine (int argc, char **argv,
  18.          int *found_labels, char **labelstring,
  19.          int *found_model, char **modelstring,
  20.          char **dfname,
  21.          int *purebeta, int *pscript, int *epp);
  22. void GiveUsage (char *execname);
  23. char *cleanup_mstring (char *s);
  24. /* End of local prototypes. */
  25.  
  26. #define MAXLABELS 1024
  27.  
  28. int 
  29. main (int argc, char **argv)
  30. {
  31.   char *dfname;            /* name of input data file */
  32.   int cols;            /* Number of columns found in file */
  33.   float **data;            /* main data matrix */
  34.   int ObsNum;            /* How many observations? */
  35.   char **labels;        /* labels for variables. */
  36.   char *labelstring;        /* comes out of commandline parsing. */
  37.   int found_labels;
  38.   int purebeta, pscript, epp;
  39.   int found_model;        /* is he specifying a model? */
  40.   char *modelstring;
  41.   int *maptable, labelcount;
  42.  
  43.   if (1 == CommandLine (argc, argv,
  44.             &found_labels, &labelstring,
  45.             &found_model, &modelstring,
  46.             &dfname, &purebeta, &pscript, &epp))
  47.     return 1;
  48.  
  49.   if (found_model && (!found_labels))
  50.     {
  51.       fprintf (stderr, "If you specify a model on the commandline,\n");
  52.       fprintf (stderr, "you should also specify data labels.\n");
  53.       return 1;
  54.     }
  55.  
  56.   if (found_labels && (!found_model))
  57.     {
  58.       modelstring = strdup (labelstring);
  59.       found_model = TRUE;
  60.     }                /* not writing a modelstring is just saying "use
  61.         everything in the labels */
  62.  
  63.   if (NULL ==
  64.       (data = LoadFile (dfname, &cols, &ObsNum,
  65.             found_model, labelstring, modelstring,
  66.             &labels, &maptable, &labelcount)))
  67.     {
  68.       fprintf (stderr, "Errors in reading data.\n");
  69.       fprintf (stderr, "Say 'ols -h' for help.\n");
  70.       return 1;
  71.     }
  72.   /* at return,
  73.         cols is #columns in what is used.
  74.         ObsNum is #rows loaded from disk.
  75.         cols may have nothing to do with NF of labelstring.
  76.         Labels come back whether or not found_model.
  77.         maptable always comes back. */
  78.  
  79.   free (labelstring);
  80.   free (modelstring);
  81.  
  82.   /* Worry about weirdo datasets.*/
  83.   if ((ObsNum == 0) || (cols <= 1))
  84.     {
  85.       fprintf (stderr, "Nonsense dataset.\n");
  86.       return 1;
  87.     }
  88.   if (ObsNum <= (cols - 1))
  89.     {
  90.       fprintf (stderr, "Too few observations for fitting a line.\n");
  91.       return 1;
  92.     }
  93.   /* End of checks for weirdo datasets. */
  94.  
  95.   if (1 == ols (labels, data, cols - 1, ObsNum,
  96.         purebeta, pscript, epp, maptable, labelcount))
  97.     {
  98.       fprintf (stderr, "Fatal errors, aborting.\n");
  99.       return 1;
  100.     }
  101.  
  102.   return 0;
  103. }
  104.  
  105. void 
  106. GiveUsage (char *execname)
  107. {
  108.   fprintf (stderr, "\nThis is a tool to estimate linear regressions (OLS).\nUsage:\n");
  109.   fprintf (stderr, "\n\t%s [datafile] [-l labels_string] [-m model_spec] [-p] [-raw]\n", execname);
  110.   fprintf (stderr, "\nFinished example of usage:\n\n");
  111.   fprintf (stderr, "\t%s abc.dat -l 'x y z' -m 'z = x'", execname);
  112.   fprintf (stderr, "\n\nThis is just a quick summary; lookup man pages for more.\n");
  113.   fprintf (stderr, "\nThis is version %s.\n", PATCHLEVEL);
  114. }
  115.  
  116. int 
  117. CommandLine (int argc, char **argv,
  118.          int *found_labels, char **labelstring,
  119.          int *found_model, char **modelstring,
  120.          char **dfname,
  121.          int *purebeta, int *pscript, int *epp)
  122. {
  123.   int i, found_df, parsed;
  124.  
  125.   found_df = *found_labels = *found_model =
  126.     *purebeta = *pscript = *epp = FALSE;
  127.   *modelstring = *labelstring = NULL;
  128.   for (i = 1; i < argc; i++)
  129.     {
  130.       if (0 == strncmp (argv[i], "-", 1))
  131.     {
  132.       parsed = FALSE;
  133.  
  134.       /* -h or -H */
  135.       if (
  136.            (0 == strncmp (argv[i], "-h", 2))
  137.            ||
  138.            (0 == strncmp (argv[i], "-H", 2))
  139.         )
  140.         {
  141.           GiveUsage (argv[0]);
  142.           return 1;
  143.         }
  144.  
  145.       /* -l */
  146.       if (0 == strncmp (argv[i], "-l", 2))
  147.         {
  148.           *labelstring = strdup (argv[++i]);
  149.           parsed = TRUE;
  150.           *found_labels = TRUE;
  151.         }
  152.  
  153.       /* -m */
  154.       if (0 == strncmp (argv[i], "-m", 2))
  155.         {
  156.           if (NULL ==
  157.           (*modelstring = cleanup_mstring (strdup (argv[++i]))))
  158.         {
  159.           fprintf (stderr, "Error in model description.\n");
  160.           return 1;
  161.         };
  162.           parsed = TRUE;
  163.           *found_model = TRUE;
  164.         }
  165.  
  166.       /* -raw */
  167.       if (0 == strncmp (argv[i], "-raw", 4))
  168.         {
  169.           parsed = TRUE;
  170.           *purebeta = TRUE;
  171.         }
  172.  
  173.       /* -p */
  174.       if (0 == strncmp (argv[i], "-p", 2))
  175.         {
  176.           parsed = TRUE;
  177.           *pscript = TRUE;
  178.         }
  179.  
  180.       /* -epp */
  181.       if (0 == strncmp (argv[i], "-epp", 4))
  182.         {
  183.           parsed = TRUE;
  184.           *epp = TRUE;
  185.         }
  186.  
  187.       if (!parsed)
  188.         {
  189.           fprintf (stderr,
  190.                "Unrecognised switch: %s\n", argv[i]);
  191.           return 1;
  192.         }
  193.     }
  194.       else
  195.     /* if it's not "-" something then it's the dfname. */
  196.     {
  197.       if (found_df)
  198.         {
  199.           fprintf (stderr,
  200.                "You can't have two filenames on the commandline.\n");
  201.           fprintf (stderr,
  202.                "%s was supposed to be the datafile but you claim %s is a datafile too.\n", *dfname, argv[i]);
  203.           fprintf (stderr, "Say 'ols -h' for help.\n");
  204.           return 1;
  205.         }
  206.       *dfname = (char *) strdup (argv[i]);
  207.       found_df = TRUE;
  208.     }
  209.     }
  210.  
  211.   /* Now we need to make sure the various flags are not incompatible.
  212.     The full list of flags is h l m beta p epp
  213.     Incompatibilities:
  214.         Errors of mixing h with others are ignored.
  215.         Only one of beta, p and epp are ok.
  216.     We'll do a cheap implementation:
  217.     */
  218.   if (((*epp) + (*pscript) + (*purebeta)) > 1)
  219.     {
  220.       fprintf (stderr,
  221.            "Atmost one of these three flags '-p', '-beta' and '-epp'\n");
  222.       fprintf (stderr, "can be present at a time.\n");
  223.       return 1;
  224.     }
  225.  
  226.   /* if you still don't have a dfname, it's coming from StdIn. */
  227.   if (!found_df)
  228.     *dfname = (char *) strdup ("-");
  229.   return 0;
  230. }
  231.  
  232. char *
  233. cleanup_mstring (char *s)
  234.      /* given a string "y = x z" produce "x z y".
  235. Modifies the data which the pointer s points to.*/
  236. {
  237.   char *words[2];
  238.  
  239.   if (2 != split (s, words, 2, "="))
  240.     {
  241.       fprintf (stderr, "Model definition must look like 'y = x z'.\n");
  242.       return NULL;
  243.     }
  244.   words[0] = strdup (words[0]);
  245.   words[1] = strdup (words[1]);
  246.   /* So words are no longer pointers into contents of s */
  247.  
  248.   /* Now we go around setting up s correctly. */
  249.   s = strcpy (s, words[1]);
  250.   s = strcat (s, " ");
  251.   s = strcat (s, words[0]);
  252.   free (words[0]);
  253.   free (words[1]);
  254.  
  255.   return s;
  256. }
  257.